<!doctype html public "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
<html>
<head>
<title>
JsWs Overview
</title>
<link rel ="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script>
function asd() {
	
		parent.document.title="server.js Overview";
	
}
</script>
</head>
<body bgcolor="white" onload="asd();">

<!-- ========== START OF NAVBAR ========== -->
<a name="navbar_top"><!-- --></a>
<table border="0" width="100%" cellpadding="1" cellspacing="0">
<tr>
<td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1">
<a name="navbar_top_firstrow"><!-- --></a>
<table border="0" cellpadding="0" cellspacing="3">
  <tr align="center" valign="top">
  
  
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a>&nbsp;</td>
  <td bgcolor="#FFFFFF" class="NavBarCell1Rev">	&nbsp;<font class="NavBarFont1Rev"><b>File</b></font>&nbsp;</td>
  

  <td bgcolor="#FFFFFF" class="NavBarCell1"> 	<font class="NavBarFont1">Class</font>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a>&nbsp;</td>
  </tr>
</table>
</td>
<td bgcolor="#EEEEFF" align="right" valign="top">
<em>
<b>JsWs</b></em>
</td>
</tr>

<tr>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</font></td>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
  <a href="index.html" target="_top"><b>FRAMES</b></a>  &nbsp;
&nbsp;<a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a>
&nbsp;&nbsp;
<script>
  <!--
  if(window==top) {
    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
  }
  //-->
</script>
<noscript>
<a href="allclasses-noframe.html" target=""><b>All Classes</b></a>
</noscript>
</font></td>
</tr>
</table>
<!-- =========== END OF NAVBAR =========== -->

<hr>
<center>
	
	   <h2>server.js</h2>
	
</center>

	


<h4>Summary</h4>
<p>
	
		No overview generated for 'server.js'<BR/><BR/>
	
</p>

<hr>


    <table border="1" cellpadding="3" cellspacing="0" width="100%">
    <tr bgcolor="#CCCCFF" class="TableHeadingColor">
    <td colspan=2><font size="+2">
    
        <b>Class Summary</b>
    
    </font></td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="JsWs.html">JsWs</a></b></td>
    <td>JsWs server object.</td>
    </tr>
    
    </table>
    <hr/> 


<!-- ========== METHOD SUMMARY =========== -->

<!-- ========== END METHOD SUMMARY =========== -->


        <pre class="sourceview"><span class="comment">/* ***** BEGIN LICENSE BLOCK *****
 *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is JsWs.
 *
 * The Initial Developer of the Original Code is
 * Chris Winberry.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 * ***** END LICENSE BLOCK ***** */</span>
<span class="comment">// netscape.security.PrivilegeManager.enablePrivilege("UniversalPreferencesRead UniversalPreferencesWrite UniversalBrowserRead UniversalBrowserWrite UniversalXPConnect")</span>

<span class="comment">/********************************************************************************
 * JsWs
 *******************************************************************************/</span>
<span class="comment">/**
 * <span class="attrib">@class</span> JsWs server object. Exposes high-level starting and stopping of the server
 * <span class="attrib">@contructor</span>
 * <span class="attrib">@param</span> {Number} port Port to listen on
 * <span class="attrib">@param</span> {Boolean} localOnly Flag indicating whether to ignore requests from remote addresses
 * <span class="attrib">@param</span> {Boolean} threaded Flag indicating whether the server should run in thread separate
 *  from the main JS/GUI thread
 */</span>
<span class="reserved">function</span> JsWs (port, localOnly, threaded) {
	<span class="comment">/** <span class="attrib">@private</span> */</span>
	<span class="reserved">this</span>.port = port;
	<span class="comment">/** <span class="attrib">@private</span> */</span>
	<span class="reserved">this</span>.localOnly = !!localOnly;
	<span class="comment">/** <span class="attrib">@private</span> */</span>
	<span class="reserved">this</span>.isThreaded = !!threaded;

	<span class="comment">/**
	 * Hash to store server scoped data for sharing between requests and pages
	 * <span class="attrib">@type</span> Hash
	 */</span>
	<span class="reserved">this</span>.state = new Array();
	<span class="comment">/** <span class="attrib">@private</span> */</span>
	<span class="reserved">this</span>.modules = new Array();
	<span class="comment">/**
	 * Path to the server's root
	 * <span class="attrib">@type</span> nsILocalFile
	 */</span>
	<span class="reserved">this</span>.root = Cc[<span class="literal">"@mozilla.org/file/directory_service;1"</span>].
		getService(Ci.nsIProperties).
		get(<span class="literal">'ProfD'</span>, Ci.nsILocalFile);
	<span class="comment">/**
	 * Path to the server's document root
	 * <span class="attrib">@type</span> nsILocalFile
	 */</span>
	<span class="reserved">this</span>.serverRoot = <span class="reserved">this</span>.root.clone();
	<span class="reserved">this</span>.tools.appendPath(<span class="reserved">this</span>.serverRoot, JSWS_ROOT);

	<span class="reserved">this</span>.documentRoot = <span class="reserved">this</span>.serverRoot.clone();
	<span class="reserved">this</span>.tools.appendPath(<span class="reserved">this</span>.documentRoot, JSWS_DOCROOT);

	<span class="reserved">this</span>.loadModules();

	<span class="reserved">this</span>.initModules();
}

JsWs.<span class="reserved">prototype</span>.initModules = <span class="reserved">function</span> () {
	<span class="reserved">for</span> (var key in <span class="reserved">this</span>.modules) {
		<span class="reserved">if</span> (<span class="reserved">this</span>.modules[key].initPage) {
			var mappedModule = <span class="reserved">this</span>.modules[key];
			var handlerObj = {
					<span class="literal">"write"</span> : <span class="reserved">function</span> () {},
					<span class="literal">"destroy"</span> : <span class="reserved">function</span> () {}
					}
			var request = new Request();
			request.path = mappedModule.virtualPath
				+ mappedModule.initPage;
			var response = new Response(handlerObj);
			var script = new ScriptContext(<span class="reserved">this</span>, request.path);
			var codeHost = new EvalCodeHost(<span class="reserved">this</span>, request, response, script);

			try {
				codeHost.require(
					mappedModule.virtualPath +
					mappedModule.initPage
					);
				JsWs.log(<span class="literal">"Module \"</span><span class="literal">" + mappedModule.name + "</span>\<span class="literal">" initialized"</span>);
			} catch (ex) {
				JsWs.log(<span class="literal">"Init page for module \"</span><span class="literal">" + mappedModule.name + "</span>\<span class="literal">" failed : "</span> + ex);
			} finally {
				request.destroy();
				request = null;
				response.destroy();
				response = null;
				script.destroy();
				script = null;
				codeHost.destroy();
				codeHost = null;
			}
		}
	}
}

<span class="comment">/** <span class="attrib">@private</span> */</span>
JsWs.<span class="reserved">prototype</span>.QueryInterface = <span class="reserved">function</span> (aIID) {
	<span class="reserved">if</span>(
		!aIID.equals(Ci.nsISupports) &amp;&amp;
		!aIID.equals(Ci.nsIRunnable) &amp;&amp;
		!aIID.equals(Ci.nsIClassInfo)
		)
		throw Components.results.NS_ERROR_NO_INTERFACE;

	<span class="reserved">return</span> <span class="reserved">this</span>;
}


<span class="comment">/** Starts the server listening */</span>
JsWs.<span class="reserved">prototype</span>.start = <span class="reserved">function</span> () {
	<span class="comment">/* Something wierd is going on with the math functions.
	 * Looks like FF has major problems if the math library is
	 * called/loaded for the first time by something other
	 * than the main JS thread. Hence the stupidness that follows...
	 * KLUDGE ZONE */</span>
	parseInt(<span class="literal">"1"</span>);
	new Number(1);
	<span class="comment">/* KLUDGE ZONE */</span>

	var currentThread = Cc[<span class="literal">"@mozilla.org/thread;1"</span>]
		.createInstance(Ci.nsIThread)
		.currentThread;

	<span class="reserved">this</span>.log(<span class="literal">"Server Starting [port:"</span> + <span class="reserved">this</span>.port + <span class="literal">"]"</span>);
	<span class="reserved">this</span>.eqs = Cc[<span class="literal">"@mozilla.org/event-queue-service;1"</span>]
		.getService(Ci.nsIEventQueueService);
	<span class="reserved">this</span>.server = Cc[<span class="literal">"@mozilla.org/network/server-socket;1"</span>]
		.createInstance(Ci.nsIServerSocket);
	<span class="reserved">this</span>.server.init(<span class="reserved">this</span>.port, <span class="reserved">this</span>.localOnly, -1);
	<span class="reserved">if</span> (<span class="reserved">this</span>.isThreaded) {
		<span class="reserved">this</span>.thread = Cc[<span class="literal">"@mozilla.org/thread;1"</span>]
			.createInstance(Ci.nsIThread);
		<span class="reserved">this</span>.thread.init(
			<span class="reserved">this</span>,
			0,
			Ci.nsIThread.PRIORITY_LOW,
			Ci.nsIThread.SCOPE_LOCAL,
			Ci.nsIThread.STATE_UNJOINABLE
			);
	}
	<span class="reserved">else</span> {
		<span class="reserved">this</span>.server.asyncListen(<span class="reserved">this</span>);
	}
	<span class="reserved">this</span>.log(<span class="literal">"Server Started"</span>);
}


<span class="comment">/**
 * Runs cleanup on internal objects
 */</span>
JsWs.<span class="reserved">prototype</span>.destroy = <span class="reserved">function</span> () {
	<span class="reserved">this</span>.stop();
	<span class="reserved">this</span>.eqs = null;
	<span class="reserved">this</span>.server = null;
	<span class="reserved">this</span>.state = null;
	<span class="reserved">this</span>.modules = null;
	<span class="reserved">this</span>.root = null;
	<span class="reserved">this</span>.documentRoot = null;
}


<span class="comment">/** Stops the server listening */</span>
JsWs.<span class="reserved">prototype</span>.stop = <span class="reserved">function</span> () {
	<span class="reserved">this</span>.log(<span class="literal">"Stopping..."</span>);
	<span class="reserved">if</span> (<span class="reserved">this</span>.isThreaded &amp;&amp; <span class="reserved">this</span>.thread)
		<span class="reserved">this</span>.thread.interrupt();
	<span class="reserved">if</span> (<span class="reserved">this</span>.server)
		<span class="reserved">this</span>.server.close();
	<span class="reserved">this</span>.log(<span class="literal">"done"</span>);
}


<span class="comment">/** <span class="attrib">@private</span> */</span>
JsWs.<span class="reserved">prototype</span>.run = <span class="reserved">function</span> () {
	<span class="reserved">this</span>.eq = <span class="reserved">this</span>.eqs.createFromIThread(<span class="reserved">this</span>.thread, false);
	<span class="reserved">this</span>.server.asyncListen(<span class="reserved">this</span>);
	<span class="reserved">this</span>.eq.eventLoop();
	<span class="reserved">this</span>.eq.processPendingEvents();
	<span class="reserved">this</span>.eq.stopAcceptingEvents();
	<span class="reserved">this</span>.eq.processPendingEvents();
	<span class="reserved">this</span>.eqs.destroyThreadEventQueue();
}


<span class="comment">/**
 * Logs a message to the JavaScript console
 * <span class="attrib">@param</span> {String} s Message to log
 */</span>
JsWs.log = <span class="reserved">function</span> (s) {
	var currentThread = Cc[<span class="literal">"@mozilla.org/thread;1"</span>]
		.createInstance(Ci.nsIThread)
		.currentThread;
	Cc[<span class="literal">"@mozilla.org/consoleservice;1"</span>].
		getService(Ci.nsIConsoleService).
		logStringMessage(<span class="literal">"("</span> + currentThread.priority + <span class="literal">")[JsWs] "</span> + s);
}
JsWs.<span class="reserved">prototype</span>.log = JsWs.log;

<span class="comment">/**
 * Maps a path to the appropriate module
 * <span class="attrib">@param</span> {String} path Absolute server path to find the mapped module for
 * <span class="attrib">@returns</span> Module that handles the path
 * <span class="attrib">@type</span> Module
 */</span>
JsWs.<span class="reserved">prototype</span>.mapModule = <span class="reserved">function</span> (path) {
	<span class="reserved">if</span> ((typeof path == <span class="literal">"string"</span>) || (path instanceof String))
		path = new VirtualPath(path);
	<span class="reserved">if</span> (!(path instanceof VirtualPath))
		throw(new ExParamError(<span class="literal">"Parameter \"</span>path\<span class="literal">" is of an unexpected type ("</span> + typeof path + <span class="literal">")"</span>, 0, null, arguments));

	var mappedModule = <span class="reserved">this</span>.modules[JSWS_MODULES_ROOTKEY];
	<span class="reserved">for</span> (var key in <span class="reserved">this</span>.modules) {
		<span class="reserved">if</span> (key == JSWS_MODULES_ROOTKEY)
			continue;
		<span class="reserved">if</span> (path.path.indexOf(<span class="reserved">this</span>.modules[key].virtualPath) == 0)
			<span class="reserved">if</span> (<span class="reserved">this</span>.modules[key].virtualPath.length &gt; mappedModule.virtualPath.length)
				mappedModule = <span class="reserved">this</span>.modules[key];
	}

	<span class="reserved">return</span>(mappedModule);
}

<span class="comment">/** <span class="attrib">@private</span> */</span>
JsWs.<span class="reserved">prototype</span>.onSocketAccepted = <span class="reserved">function</span> (socket, transport) {
	new JsWsConnectionHandler(<span class="reserved">this</span>, socket, transport);
}

<span class="comment">/** <span class="attrib">@private</span> */</span>
JsWs.<span class="reserved">prototype</span>.onStopListening = <span class="reserved">function</span> (socket, status) {}

<span class="comment">/** TODO */</span>
JsWs.tools = {

	<span class="comment">//"normalizePath": function (path) {</span>
	<span class="comment">//		return(path.replace(/(\/|\\)/g, VirtualPath.sysSeparator));</span>
	<span class="comment">//	},</span>

	<span class="literal">"htmlEscape"</span>: <span class="reserved">function</span> (content) {
			<span class="reserved">return</span>(content.replace(/&amp;/g, <span class="literal">'&amp;amp;'</span>).replace(/&lt;/g, <span class="literal">'&amp;lt;'</span>).replace(/&gt;/g, <span class="literal">'&amp;gt;'</span>).replace(/\n/g, <span class="literal">"&lt;br&gt;\n"</span>));
		},

	<span class="literal">"appendPath"</span>: <span class="reserved">function</span> (file, path) {
		var oLocalFile = file.QueryInterface(Ci.nsILocalFile);
		var pathParts = path.split(/(?:\/|\\)+/);
		<span class="reserved">for</span> (var i = 0; i &lt; pathParts.length; i++) {
			<span class="reserved">if</span> (pathParts[i] == <span class="literal">'.'</span>) { continue; }
			<span class="reserved">if</span> (pathParts[i] == <span class="literal">'..'</span>) {
				oLocalFile = oLocalFile.parent;
			} <span class="reserved">else</span> {
				oLocalFile.append(pathParts[i]);
			}
		}
		oLocalFile.normalize();
	},

	<span class="literal">"enumTypes"</span>: <span class="reserved">function</span> (type, target) {
		var objs = new Array();
		<span class="reserved">if</span> (target == null) { target = window; }

		<span class="reserved">for</span> (var i in target) {
			try {
				<span class="reserved">if</span> (type == null | typeof target[i] == type) {
					objs[i] = typeof target[i];
				}
			} catch (e) {
				<span class="comment">// Hmmm</span>
			}
		}
		<span class="reserved">return</span>(objs);
	},

	<span class="literal">"enumFunctions"</span>: <span class="reserved">function</span> (target) {<span class="reserved">return</span>(enumTypes(<span class="literal">"function"</span>, target)); },

	<span class="literal">"enumStrings"</span>: <span class="reserved">function</span> (target) { <span class="reserved">return</span>(enumTypes(<span class="literal">"string"</span>, target)); },

	<span class="literal">"enumObjects"</span>: <span class="reserved">function</span> (target) { <span class="reserved">return</span>(enumTypes(<span class="literal">"object"</span>, target)); },

	<span class="literal">"enumNumbers"</span>: <span class="reserved">function</span> (target) { <span class="reserved">return</span>(enumTypes(<span class="literal">"number"</span>, target)); },

	<span class="literal">"enumBools"</span>: <span class="reserved">function</span> (target) { <span class="reserved">return</span>(enumTypes(<span class="literal">"boolean"</span>, target)); }

}
JsWs.<span class="reserved">prototype</span>.tools = JsWs.tools;

<span class="comment">/** <span class="attrib">@private</span> */</span>
JsWs.<span class="reserved">prototype</span>.loadModules = <span class="reserved">function</span> () {
	<span class="reserved">if</span> (<span class="reserved">this</span>.modules &amp;&amp; <span class="reserved">this</span>.modules.length &gt; 0)
		<span class="reserved">return</span>;
	<span class="reserved">this</span>.modules = Module.loadFromPrefs(JSWS_PREF_MODULES_ROOT);

	var module = new Module(JSWS_MODULES_ROOTKEY);
	module.setProperty(JSWS_MODULES_NAMEKEY, JSWS_MODULES_ROOTKEY);
	module.setProperty(JSWS_MODULES_EXTENSIONPATHKEY, <span class="reserved">this</span>.serverRoot.path);
	module.setProperty(JSWS_MODULES_CONTENTPATHKEY, JSWS_DOCROOT);
	module.setProperty(JSWS_MODULES_VIRTUALPATHKEY, <span class="literal">"/"</span>);
	module.setProperty(JSWS_MODULES_HANDLERKEY, <span class="literal">"/../pageHandler."</span> +  JSWS_SCRIPT_FILEEXT);
	module.setProperty(JSWS_MODULES_STARTPAGEKEY, <span class="literal">"/index."</span> +  JSWS_SCRIPT_FILEEXT);
	<span class="reserved">this</span>.modules[JSWS_MODULES_ROOTKEY] = module;
}

<span class="comment">/** <span class="attrib">@private</span> */</span>
JsWs.<span class="reserved">prototype</span>.getInterfaces = <span class="reserved">function</span> (count) {
	var ifaces = [
		Ci.nsISupports,
		Ci.nsIRunnable,
		Ci.nsIClassInfo
		];
	count.value = ifaces.length;
	<span class="reserved">return</span> ifaces;
}


<span class="comment">/** <span class="attrib">@private</span> */</span>
JsWs.<span class="reserved">prototype</span>.getHelperForLanguage = <span class="reserved">function</span> (language) {
	<span class="reserved">return</span> null;
}

<span class="comment">// TODO: smart handling of string vs. nsIFile paths</span>
</pre>
	<hr>



<!-- ========== START OF NAVBAR ========== -->
<a name="navbar_top"><!-- --></a>
<table border="0" width="100%" cellpadding="1" cellspacing="0">
<tr>
<td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1">
<a name="navbar_top_firstrow"><!-- --></a>
<table border="0" cellpadding="0" cellspacing="3">
  <tr align="center" valign="top">
  
  
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a>&nbsp;</td>
  <td bgcolor="#FFFFFF" class="NavBarCell1Rev">	&nbsp;<font class="NavBarFont1Rev"><b>File</b></font>&nbsp;</td>
  

  <td bgcolor="#FFFFFF" class="NavBarCell1"> <font class="NavBarFont1">Class</font>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a>&nbsp;</td>
  </tr>
</table>
</td>
<td bgcolor="#EEEEFF" align="right" valign="top"><em>
<b>JsWs</b></em>
</td>
</tr>

<tr>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</font></td>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
  <a href="index.html" target="_top"><b>FRAMES</b></a>  &nbsp;
&nbsp;<a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a>
&nbsp;&nbsp;
<script>
  <!--
  if(window==top) {
    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
  }
  //-->
</script>
<noscript>
<a href="allclasses-noframe.html" target=""><b>All Classes</b></a>
</noscript>
</font></td>
</tr>
</table>
<!-- =========== END OF NAVBAR =========== -->

<hr>
<font size="-1">

</font>
<div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Thu Nov  8 22:50:16 2007</div>
</body>
</html>
